﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp.智能枚举;

public abstract class Enumeration<TEnum> : IEquatable<Enumeration<TEnum>> where TEnum : Enumeration<TEnum>
{
    private static readonly Dictionary<int, TEnum?> Enumerations = GetEnumerations();

    /// <summary>
    /// 枚举类型
    /// </summary>
    private static Type EnumType = typeof(TEnum);

    protected Enumeration(int value, string name)
    {
        Value = value;
        Name = name; 
    }

    /// <summary>
    /// 名称
    /// </summary>
    public string Name { get; protected init; }

    /// <summary>
    /// 值
    /// </summary>
    public int Value { get; protected init; }

    public static TEnum? FromName(string name) => Enumerations.Values.SingleOrDefault(x => x.Name == name);

    public static TEnum? FromValue(int value) => Enumerations.TryGetValue(value, out var enumeration) ? enumeration : default;

    public bool Equals(Enumeration<TEnum>? other) => other is not null && GetType() == other.GetType() && Value == other.Value;

    public override bool Equals(object? obj) => obj is Enumeration<TEnum> other && Equals(other);

    public override int GetHashCode() => HashCode.Combine(Value, Name);

    private static Dictionary<int, TEnum?> GetEnumerations() 
    {
        if (EnumType is null)
        {
            EnumType = typeof(TEnum);
        }
       return  EnumType
            .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy)
            .Where(x => EnumType.IsAssignableFrom(x.FieldType))
            .Select(x => (TEnum?)x.GetValue(default)).ToDictionary(x => x?.Value ?? 0);
    }
}
